package com.share.controller;

import cn.hutool.crypto.SecureUtil;
import com.share.utils.MyJWTUtil;
import com.share.model.Result;
import com.share.model.User;
import com.share.service.UserService;
import com.share.utils.UserUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.NotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private CodeController codeController;

    // 用户名 + 手机号 + 手机号验证码 + 密码 + 确认密码
    @PostMapping("/register")
    public void register(@RequestBody @Validated User user) {
        // 1. 首先检查密码和确认密码
        if (!user.getPassword().equals(user.getRePassword())) {
            throw new IllegalArgumentException("输入的两次密码不一致");
        }

        // 2. 校验手机号是否已经注册
        User registerUser = userService.getUserByPhone(user.getPhone());
        if (registerUser != null) {     // 该手机号已经注册
            throw new IllegalArgumentException("该手机号已存在，请登录");
        }

        // 3. 校验用户名是否已经被注册
        if (userService.isExists(user.getUsername()) != null){
            throw new IllegalArgumentException("该用户名已存在，请登录");
        }

        // 4. 校验手机号验证码是否正确
        if (!codeController.verifyPhoneCode(user.getPhone(), user.getPhoneCode())) {
            throw new IllegalArgumentException("验证码错误，请重新输入");
        }

        // 5. 满足条件写入到数据库
        user.setPassword(SecureUtil.sha256(user.getPassword()));
        userService.addUser(user);
    }

    // 用户名 + 密码 + 真人验证
    // token存储：用户 id + token值（用户id、时间戳、文件id、回收站id）
    @GetMapping("/login/username")
    public Result login(@RequestParam String username, @RequestParam String password, @RequestParam String code) throws NotFoundException {
        // 1. 校验真人验证码是否正确
        if (!codeController.verifyAuthCode(code)) {
            throw new IllegalArgumentException("验证码错误，请重新输入");
        }

        // 2. 校验用户名是否存在 不存在提示去注册
        User user = userService.isExists(username);
        if (user == null) {
            throw new NotFoundException("该用户不存在，请先注册");
        }

        // 3. 用户存在校验密码
        if (!SecureUtil.sha256(password).equals(user.getPassword())) {
            throw new IllegalArgumentException("密码错误，请重新输入");
        }

        // 4. 登录成功 生成 token 并返回
        String token = MyJWTUtil.createToken(user.getId());

        // 5. 将 token 放入 redis 中
        userService.setTokenToRedis(user.getId(), token);
        return Result.success("登录成功", token);
    }

    // 手机号没有注册时直接跳转到修改密码页面  让修改默认密码
    @GetMapping("/login/phone")
    public Result login(@RequestParam String phone, @RequestParam String code) {
        // 1. 校验手机号是否已经注册
        User user = userService.getUserByPhone(phone);
        if (user == null) {     // 该手机号没有注册
            user = new User();
            user.setUsername(phone);
            user.setPassword(phone.substring(4));       // 从手机号第五位开始截取得到后六位作为默认密码
            user.setPhone(phone);
            userService.addUser(user);
            // 4. 将 token 放入 redis ThreadLocal 中
            String token = MyJWTUtil.createToken(user.getId());
            userService.setTokenToRedis(user.getId(), token);
            return Result.success("该用户不存在，已注册成功");
        }

        // 2. 校验手机号验证码
        if (!codeController.verifyPhoneCode(phone, code)) {
            throw new IllegalArgumentException("验证码错误，请重新输入");
        }

        // 3. 登录成功 生成 token 并返回
        String token = MyJWTUtil.createToken(user.getId());

        // 4. 将 token 放入 redis ThreadLocal 中
        userService.setTokenToRedis(user.getId(), token);
        return Result.success("登录成功", token);
    }

    // 获取用户名 + 昵称 + 头像 + 文件目录 + 回收站目录
    // 拿到 token中的用户id 去 redis中对比存储的用户 token 判断相同 不同的话做单点登录
    @GetMapping("/userInfo")
    public User userInfo() {
//        User user = (User) request.getSession(false).getAttribute("user");
        User user = userService.getUserById(UserUtils.get());
        log.info("user:{}",user);
        return user;
    }

    // 退出登录 销毁 token
    @GetMapping("/logout")
    public void logout() {
//        User user = (User) request.getSession(false).getAttribute("user");
        Long userId = UserUtils.get();
        log.info("userId:{}",userId);
        // 2. 清除 redis ThreadLocal 中的用户信息
        UserUtils.remove();
        userService.removeTokenFromRedis(userId);
    }

    // 忘记密码：手机号 + 手机号验证码 + 新密码 + 确认密码
    @PostMapping("/updatePwd")
    public void updatePwd(@RequestBody User user) {
        // 1. 首先检查密码和确认密码
        if (!user.getPassword().equals(user.getRePassword())) {
            throw new IllegalArgumentException("输入的两次密码不一致");
        }

        // 2. 校验手机号是否已经注册
        User registerUser = userService.getUserByPhone(user.getPhone());
        if (registerUser == null) {     // 该手机号没有注册
            throw new IllegalArgumentException("该手机号并没有被注册");
        }

        // 3. 校验手机号验证码是否正确
        if (!codeController.verifyPhoneCode(user.getPhone(), user.getPhoneCode())) {
            throw new IllegalArgumentException("验证码错误，请重新输入");
        }

        // 4. 更新用户信息
        // 获取全局中的用户信息 得到用户 id 进行修改
        Long userId = UserUtils.get();
        user.setId(userId);
        user.setPassword(SecureUtil.sha256(user.getPassword()));
        userService.updateUser(user);

        // 5. 清除 redis 中原有的该用户 id
        userService.removeTokenFromRedis(userId);
    }

    // 修改用户信息
    @PutMapping("/update")
    public void update(@RequestBody User user) {
        user.setId(UserUtils.get());       // 用拦截器获取 token 中的用户 id
        userService.updateUser(user);
    }

}
